package com.ruoyi.web.controller.energy;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.energy.domain.EmsDevice;
import com.ruoyi.energy.domain.EmsEnergyData;
import com.ruoyi.energy.domain.EmsTimeSeriesData;
import com.ruoyi.energy.service.IEmsDeviceService;
import com.ruoyi.energy.service.IEmsEnergyDataService;
import com.ruoyi.energy.service.ITDengineTimeSeriesService;

/**
 * 综合能源数据采集Controller
 * 
 * @author ruoyi
 * @date 2024-01-20
 */
@RestController
@RequestMapping("/energy/collection")
public class EmsDataCollectionController extends BaseController {
    
    @Autowired
    private IEmsDeviceService emsDeviceService;

    @Autowired
    private IEmsEnergyDataService emsEnergyDataService;

    @Autowired
    private ITDengineTimeSeriesService tdengineTimeSeriesService;

    /**
     * 接收电力数据
     */
    @PostMapping("/electric")
    @Log(title = "电力数据采集", businessType = BusinessType.INSERT)
    public AjaxResult receiveElectricData(@RequestBody Map<String, Object> dataMap) {
        try {
            // 验证设备
            EmsDevice device = validateDevice(dataMap, "1");
            
            // 构建电力数据
            EmsEnergyData energyData = buildElectricData(device, dataMap);
            
            // 保存数据
            emsEnergyDataService.insertEmsEnergyData(energyData);
            
            return success("电力数据接收成功");
        } catch (Exception e) {
            logger.error("电力数据接收失败", e);
            return error("电力数据接收失败：" + e.getMessage());
        }
    }

    /**
     * 接收水力数据
     */
    @PostMapping("/water")
    @Log(title = "水力数据采集", businessType = BusinessType.INSERT)
    public AjaxResult receiveWaterData(@RequestBody Map<String, Object> dataMap) {
        try {
            // 验证设备
            EmsDevice device = validateDevice(dataMap, "2");
            
            // 构建水力数据
            EmsEnergyData energyData = buildWaterData(device, dataMap);
            
            // 保存数据
            emsEnergyDataService.insertEmsEnergyData(energyData);
            
            return success("水力数据接收成功");
        } catch (Exception e) {
            logger.error("水力数据接收失败", e);
            return error("水力数据接收失败：" + e.getMessage());
        }
    }

    /**
     * 接收燃气数据
     */
    @PostMapping("/gas")
    @Log(title = "燃气数据采集", businessType = BusinessType.INSERT)
    public AjaxResult receiveGasData(@RequestBody Map<String, Object> dataMap) {
        try {
            // 验证设备
            EmsDevice device = validateDevice(dataMap, "3");
            
            // 构建燃气数据
            EmsEnergyData energyData = buildGasData(device, dataMap);
            
            // 保存数据
            emsEnergyDataService.insertEmsEnergyData(energyData);
            
            return success("燃气数据接收成功");
        } catch (Exception e) {
            logger.error("燃气数据接收失败", e);
            return error("燃气数据接收失败：" + e.getMessage());
        }
    }

    /**
     * 通用数据接收接口
     */
    @PostMapping("/receive")
    @Log(title = "综合能源数据采集", businessType = BusinessType.INSERT)
    public AjaxResult receiveData(@RequestBody Map<String, Object> dataMap) {
        try {
            String energyType = (String) dataMap.get("energyType");
            if (StringUtils.isEmpty(energyType)) {
                throw new ServiceException("能源类型不能为空");
            }
            
            // 验证设备
            EmsDevice device = validateDevice(dataMap, energyType);
            
            // 根据能源类型构建数据
            EmsEnergyData energyData;
            switch (energyType) {
                case "1":
                    energyData = buildElectricData(device, dataMap);
                    break;
                case "2":
                    energyData = buildWaterData(device, dataMap);
                    break;
                case "3":
                    energyData = buildGasData(device, dataMap);
                    break;
                default:
                    throw new ServiceException("不支持的能源类型：" + energyType);
            }
            
            // 保存数据
            emsEnergyDataService.insertEmsEnergyData(energyData);
            
            return success("数据接收成功");
        } catch (Exception e) {
            logger.error("数据接收失败", e);
            return error("数据接收失败：" + e.getMessage());
        }
    }

    /**
     * 验证设备
     */
    private EmsDevice validateDevice(Map<String, Object> dataMap, String energyType) {
        String deviceCode = (String) dataMap.get("deviceCode");
        if (StringUtils.isEmpty(deviceCode)) {
            throw new ServiceException("设备编码不能为空");
        }
        
        EmsDevice device = emsDeviceService.selectEmsDeviceByDeviceCode(deviceCode);
        if (device == null) {
            throw new ServiceException("设备不存在：" + deviceCode);
        }
        
        if (!"0".equals(device.getStatus())) {
            throw new ServiceException("设备已停用：" + deviceCode);
        }
        
        if (!energyType.equals(device.getEnergyType())) {
            throw new ServiceException("设备能源类型不匹配");
        }
        
        return device;
    }

    /**
     * 构建电力数据
     */
    private EmsEnergyData buildElectricData(EmsDevice device, Map<String, Object> dataMap) {
        EmsEnergyData energyData = new EmsEnergyData();
        energyData.setDeviceId(device.getDeviceId());
        energyData.setDeviceCode(device.getDeviceCode());
        energyData.setDeviceName(device.getDeviceName());
        energyData.setEnergyType("1");
        
        // 电力数据字段
        energyData.setVoltage(getBigDecimal(dataMap, "voltage"));
        energyData.setCurrent(getBigDecimal(dataMap, "current"));
        energyData.setPower(getBigDecimal(dataMap, "power"));
        energyData.setEnergy(getBigDecimal(dataMap, "energy"));
        energyData.setPowerFactor(getBigDecimal(dataMap, "powerFactor"));
        energyData.setFrequency(getBigDecimal(dataMap, "frequency"));
        
        // 公共字段
        energyData.setTemperature(getBigDecimal(dataMap, "temperature"));
        energyData.setHumidity(getBigDecimal(dataMap, "humidity"));
        energyData.setCollectTime(getCollectTime(dataMap));
        
        return energyData;
    }

    /**
     * 构建水力数据
     */
    private EmsEnergyData buildWaterData(EmsDevice device, Map<String, Object> dataMap) {
        EmsEnergyData energyData = new EmsEnergyData();
        energyData.setDeviceId(device.getDeviceId());
        energyData.setDeviceCode(device.getDeviceCode());
        energyData.setDeviceName(device.getDeviceName());
        energyData.setEnergyType("2");
        
        // 水力数据字段
        energyData.setFlowRate(getBigDecimal(dataMap, "flowRate"));
        energyData.setWaterConsumption(getBigDecimal(dataMap, "waterConsumption"));
        energyData.setWaterPressure(getBigDecimal(dataMap, "waterPressure"));
        energyData.setWaterTemperature(getBigDecimal(dataMap, "waterTemperature"));
        
        // 公共字段
        energyData.setTemperature(getBigDecimal(dataMap, "temperature"));
        energyData.setHumidity(getBigDecimal(dataMap, "humidity"));
        energyData.setCollectTime(getCollectTime(dataMap));
        
        return energyData;
    }

    /**
     * 构建燃气数据
     */
    private EmsEnergyData buildGasData(EmsDevice device, Map<String, Object> dataMap) {
        EmsEnergyData energyData = new EmsEnergyData();
        energyData.setDeviceId(device.getDeviceId());
        energyData.setDeviceCode(device.getDeviceCode());
        energyData.setDeviceName(device.getDeviceName());
        energyData.setEnergyType("3");
        
        // 燃气数据字段
        energyData.setGasFlow(getBigDecimal(dataMap, "gasFlow"));
        energyData.setGasConsumption(getBigDecimal(dataMap, "gasConsumption"));
        energyData.setGasPressure(getBigDecimal(dataMap, "gasPressure"));
        energyData.setGasTemperature(getBigDecimal(dataMap, "gasTemperature"));
        energyData.setCalorificValue(getBigDecimal(dataMap, "calorificValue"));
        
        // 公共字段
        energyData.setTemperature(getBigDecimal(dataMap, "temperature"));
        energyData.setHumidity(getBigDecimal(dataMap, "humidity"));
        energyData.setCollectTime(getCollectTime(dataMap));
        
        return energyData;
    }

    /**
     * 获取BigDecimal值
     */
    private BigDecimal getBigDecimal(Map<String, Object> dataMap, String key) {
        Object value = dataMap.get(key);
        if (value == null) {
            return null;
        }
        
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        } else if (value instanceof Number) {
            return new BigDecimal(value.toString());
        } else if (value instanceof String && StringUtils.isNotEmpty((String) value)) {
            try {
                return new BigDecimal((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        return null;
    }

    /**
     * 获取采集时间
     */
    private Date getCollectTime(Map<String, Object> dataMap) {
        Object collectTime = dataMap.get("collectTime");
        if (collectTime instanceof Date) {
            return (Date) collectTime;
        } else if (collectTime instanceof Long) {
            return new Date((Long) collectTime);
        } else {
            return new Date(); // 默认当前时间
        }
    }

    // ==================== TDengine数据查询接口 ====================

    /**
     * 查询设备采集数据历史记录
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:query')")
    @GetMapping("/history/{deviceCode}")
    public AjaxResult getCollectionHistory(@PathVariable String deviceCode,
                                          @RequestParam String startTime,
                                          @RequestParam String endTime,
                                          @RequestParam(defaultValue = "1") Integer pageNum,
                                          @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            Date start = DateUtils.parseDate(startTime);
            Date end = DateUtils.parseDate(endTime);

            int offset = (pageNum - 1) * pageSize;
            List<EmsTimeSeriesData> data = tdengineTimeSeriesService.selectHistoryDataByDeviceWithPage(
                deviceCode, start, end, pageSize, offset);

            // 查询总数
            long total = tdengineTimeSeriesService.countDeviceData(deviceCode, start, end);

            TableDataInfo dataTable = new TableDataInfo();
            dataTable.setRows(data);
            dataTable.setTotal(total);

            return success(dataTable);
        } catch (Exception e) {
            return error("查询设备采集历史数据失败: " + e.getMessage());
        }
    }

    /**
     * 查询设备最新采集数据
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:query')")
    @GetMapping("/latest/{deviceCode}")
    public AjaxResult getLatestCollectionData(@PathVariable String deviceCode) {
        try {
            EmsTimeSeriesData data = tdengineTimeSeriesService.selectLatestDataByDevice(deviceCode);
            return success(data);
        } catch (Exception e) {
            return error("查询设备最新采集数据失败: " + e.getMessage());
        }
    }

    /**
     * 查询设备采集数据统计
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:query')")
    @GetMapping("/statistics/{deviceCode}")
    public AjaxResult getCollectionStatistics(@PathVariable String deviceCode,
                                             @RequestParam String startTime,
                                             @RequestParam String endTime,
                                             @RequestParam(defaultValue = "1h") String interval) {
        try {
            Date start = DateUtils.parseDate(startTime);
            Date end = DateUtils.parseDate(endTime);

            List<Map<String, Object>> statistics = tdengineTimeSeriesService.selectAggregatedDataByDevice(
                deviceCode, start, end, interval);

            return success(statistics);
        } catch (Exception e) {
            return error("查询设备采集数据统计失败: " + e.getMessage());
        }
    }

    /**
     * 查询所有设备最新采集数据
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:list')")
    @GetMapping("/latest/all")
    public AjaxResult getAllLatestCollectionData() {
        try {
            List<EmsTimeSeriesData> data = tdengineTimeSeriesService.selectAllDevicesLatestData();
            return success(data);
        } catch (Exception e) {
            return error("查询所有设备最新采集数据失败: " + e.getMessage());
        }
    }

    /**
     * 查询设备采集数据质量报告
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:query')")
    @GetMapping("/quality/{deviceCode}")
    public AjaxResult getDataQualityReport(@PathVariable String deviceCode,
                                          @RequestParam String startTime,
                                          @RequestParam String endTime) {
        try {
            Date start = DateUtils.parseDate(startTime);
            Date end = DateUtils.parseDate(endTime);

            Map<String, Object> report = tdengineTimeSeriesService.selectDeviceDataQualityStatistics(
                deviceCode, start, end);

            return success(report);
        } catch (Exception e) {
            return error("查询设备数据质量报告失败: " + e.getMessage());
        }
    }

    /**
     * 查询设备采集数据总数
     */
    @PreAuthorize("@ss.hasPermi('energy:collection:query')")
    @GetMapping("/count")
    public AjaxResult getCollectionDataCount(@RequestParam(required = false) String deviceCode,
                                            @RequestParam(required = false) String startTime,
                                            @RequestParam(required = false) String endTime) {
        try {
            Date start = StringUtils.isNotEmpty(startTime) ? DateUtils.parseDate(startTime) : null;
            Date end = StringUtils.isNotEmpty(endTime) ? DateUtils.parseDate(endTime) : null;

            long count = tdengineTimeSeriesService.countDeviceData(deviceCode, start, end);

            Map<String, Object> result = new HashMap<>();
            result.put("count", count);
            result.put("deviceCode", deviceCode);
            result.put("startTime", startTime);
            result.put("endTime", endTime);

            return success(result);
        } catch (Exception e) {
            return error("查询设备采集数据总数失败: " + e.getMessage());
        }
    }
}